home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
Sherlock 2.0
/
DevLibSrc
/
Main_DevLib
/
LIBos.c
< prev
next >
Wrap
Text File
|
1996-03-12
|
7KB
|
426 lines
/*
devlib: application text and binary output routines.
source: LIBos.c.
started: December 13, 1993.
version:
September 26, 1995.
Changed loop in os from: while (c = *s++) { to: while (*s) { c = *s++.
This eliminates a Code Warrior warning.
July 17, 1994.
Added ocblanks.
June 2, 1994.
Added olong.
May 24, 1994.
Added ocnl and ocnls.
Added opads.
May 4, 1994.
Made out_bytes_offset a global variable.
April 21, 1994.
Added ofloat routine.
March 31, 1994.
Bug fix: do ecnls(2) in out_bytes only when tracing!
March 24, 1994.
Improved tracing in out_bytes.
February 13, 1994.
Added ochar.
Added opadhex.
January 27, 1994.
Bug fix: os() writes *only* to the os_text_file!
Revised os() to handle tabs correctly.
January 7, 1994.
*/
#include <LIBlib.h>
#include <LIBio.h>
#include <LIBos.h>
#include <ctype.h>
#include <string.h>
/*
Define the size of the conversion buffers.
*/
#define OS_BUF_SIZE 200
/*
Prototypes of internal routines.
*/
static void ojustify(char * buffer, int length, int field_length);
/*
Globals owned by this module.
*/
io_file * os_bytes_file = NULL; /* The file used by the os routines. */
io_file * os_text_file = NULL; /* The map output file. */
void
onl(void)
{
os("\n");
}
/*
All text file output eventually comes here.
*/
void
os(register char * s)
{
FTAG("os");
TICK(ftag);
// STATB(ftag); // Getting timing measurements is too costly here
if (s && os_text_file) {
/* Load registers from the file struct. */
register char * ptr = os_text_file -> io_file_pointer;
register long count = os_text_file -> io_file_count;
register long bufsize = os_text_file -> io_file_bufsize;
register char c;
while(*s) {
c = *s++;
/* Keep track of consecutive newlines. */
if (c == '\n') {
++io_nl_count;
io_line_count = 0;
/* This step is needed now that we are using ANSI_IO.c */
#ifdef applec
c = '\r';
#endif
}
else if (c == '\t') {
/* 4-space tabs. */
int width = (4 - (io_line_count % 4));
int i;
for (i = 0; i < width; i++) {
if (count == bufsize) {
os_text_file -> io_file_count = count;
io_write(os_text_file);
ptr = os_text_file -> io_file_buffer;
count = 0;
}
*ptr++ = ' ';
++count;
}
io_nl_count = 0;
io_line_count += width;
continue;
}
else {
io_nl_count = 0;
io_line_count++;
}
if (count == bufsize) {
os_text_file -> io_file_count = count;
io_write(os_text_file);
ptr = os_text_file -> io_file_buffer;
count = 0;
}
*ptr++ = c;
++count;
}
/* Update the file struct from the registers. */
os_text_file -> io_file_pointer = ptr;
os_text_file -> io_file_count = count;
}
// STATX(ftag); // Getting timing measurements is too costly here
}
void
oblank(void)
{
os(" ");
}
void
oblanks(register int n)
{
register int i;
for(i = 0; i < n; i++) {
oblank();
}
}
void
ocblanks(short n)
{
if (os_text_file) {
n = - os_text_file -> io_file_count;
n = min(n, os_text_file -> io_file_bufsize);
oblanks(n);
}
}
void
ochar(int c)
{
char buffer[2];
buffer [0] = c;
buffer [1] = '\0';
os(buffer);
}
/*
Output condictional newlines.
*/
void
ocnl(void)
{
if (io_nl_count == 0) {
onl();
}
}
void
ocnls(int n)
{
register int i;
for (i = n - io_nl_count; i > 0; i--) {
onl();
}
}
void
ocs(void)
{
os(", ");
}
/*
This routine must make no assumptions about size of floats.
*/
void
ofloat (register char * p, int size)
{
register long val = 0;
if (p == NULL) {
fatal(es("ofloat: NULL pointer"));
}
while(size-- > 0) {
val = *p++;
val &= 0xff;
opadhex(val, 2);
}
}
void
ohex(long hex)
{
opadhex(hex, 0);
}
void
oint(int i)
{
char buf [OS_BUF_SIZE];
sprintf(buf, "%d", i);
os(buf);
}
static void
ojustify(char * buffer, int length, int field_length)
{
if (field_length < 0) {
/* Left justify */
os(buffer);
oblanks(-field_length - length);
}
else {
/* Right justify */
oblanks(field_length - length);
os(buffer);
}
}
/*
Output a long.
*/
void
olong(long l)
{
char buf [OS_BUF_SIZE];
sprintf(buf, "%ld", l);
os(buf);
}
/*
Output a long in hex format, justified in a field of the given length.
*/
void
opadhex(long hex, int field)
{
char buf [OS_BUF_SIZE];
int n;
sprintf(buf, "%lx", hex);
n = field - strlen(buf);
while (n-- > 0) {
ochar('0');
}
os(buf);
}
void
opadlong(long l, int field)
{
char buf [OS_BUF_SIZE];
ojustify(buf, sprintf(buf, "%ld", l), field);
}
void
opadptr(void * p, int field)
{
char buf [OS_BUF_SIZE];
ojustify(buf, sprintf(buf, "%p", p), field);
}
void
opads(char * s, int field)
{
ojustify(s, strlen(s), field);
}
void
opaduint(uint ui, int field)
{
char buf [OS_BUF_SIZE];
ojustify(buf, sprintf(buf, "%u", ui), field);
}
void
opadulong(ulong ul, int field)
{
char buf [OS_BUF_SIZE];
ojustify(buf, sprintf(buf, "%lu", ul), field);
}
void
optr(void * p)
{
opadptr(p, 0);
}
void
otab(void)
{
os("\t");
}
void
otabs(register int tab_count)
{
while (tab_count-- > 0) {
os("\t");
}
}
void
ouint(uint ui)
{
opaduint(ui, 0);
}
void
oulong(ulong ul)
{
char buf [OS_BUF_SIZE];
sprintf(buf, "%lu", ul);
os(buf);
}
/*
All binary output is created using the out_bytes routine.
This routine is called very often; it should be as fast as possible.
*/
#define CHARS_PER_LINE 8
#define TAG_SIZE 26 /* 26 makes the traces look best. */
ulong out_bytes_offset = 0;
void
out_bytes(register char * byte_ptr, register ulong byte_count, char * dtag)
{
FTAG("out_bytes");
/* Load registers from the file struct. */
register char * ptr = os_bytes_file -> io_file_pointer;
register long count = os_bytes_file -> io_file_count;
register long bufsize = os_bytes_file -> io_file_bufsize;
#ifdef SHERLOCK
ulong local_offset = 0;
bool line_one_flag = TRUE;
#endif
TRACEPB(ftag, epads(dtag, TAG_SIZE); eblank());
ASSERT(os_bytes_file);
while(byte_count--) {
/* Write the file buffer if it is full. */
if (count == bufsize) {
os_bytes_file -> io_file_count = count;
io_write(os_bytes_file);
ptr = os_bytes_file -> io_file_buffer;
count = 0;
}
/* Trace the next character. */
TRACEN(ftag,
char c = *byte_ptr;
if ((local_offset % CHARS_PER_LINE) == 0) {
if (!line_one_flag) {
es(ftag); es(": "); eblanks(TAG_SIZE); eblank();
}
line_one_flag = FALSE;
epadhex(out_bytes_offset,4); es(": ");
}
epadhex(c & 0xff,2);
eblank();
if ((local_offset % CHARS_PER_LINE) == CHARS_PER_LINE-1) {
ecnl();
}
out_bytes_offset++;
local_offset++;
);
/* Put the next character into the buffer. */
*ptr++ = *byte_ptr++;
++count;
}
TRACEN(ftag, ecnl());
/* Update the file struct from the registers. */
os_bytes_file -> io_file_pointer = ptr;
os_bytes_file -> io_file_count = count;
STATX(ftag);
}